from flask import Flask, g, request
from flask_cors import CORS
from flask_mongoengine import MongoEngine
from flask_socketio import SocketIO, emit

db = MongoEngine()
users = {}


def create_app() -> Flask:
    flask_app = Flask(__name__)

    from app.config import get_config
    _get_config = get_config()
    flask_app.config.from_object(_get_config)

    ctx = flask_app.app_context()
    ctx.push()
    CORS(flask_app, support_credentials=True, cors_allowed_origins='*')

    db.init_app(flask_app)

    # TODO:分配路由
    from app.util.GreenPrint import GreenPrint
    from app.test.hello import hello_blueprint
    from app.api.student import student_blueprint
    from app.api.room import room_blueprint
    from app.api.alert import alert_blueprint
    from app.api.auth import auth_blueprint
    from app.api.sentence import sentence_blueprint
    from app.api.iotdata import iotdata_blueprint

    api = GreenPrint('api', __name__, url_prefix='/api')
    api.register_blueprint(hello_blueprint)
    api.register_blueprint(student_blueprint)
    api.register_blueprint(room_blueprint)
    api.register_blueprint(alert_blueprint)
    api.register_blueprint(auth_blueprint)
    api.register_blueprint(sentence_blueprint)
    api.register_blueprint(iotdata_blueprint)

    flask_app.register_blueprint(api)

    return flask_app


def get_socket_app(flask_app):
    from app.models.Sentence import Sentence
    from app.util.jwt import auth_check
    socket_io = SocketIO(flask_app, cors_allowed_origins='*')

    @socket_io.on('disconnect', namespace='/websocket')
    def on_disconnect():
        sid = request.sid
        if sid in users.keys():
            del users[sid]
        print(sid, 'disconnect')
        print(users, len(users))

    @socket_io.on('exit_ws', namespace='/websocket')
    def on_disconnect():
        sid = request.sid
        if sid in users.keys():
            del users[sid]
        print(sid, 'disconnect')
        print(users, len(users))

    @socket_io.on('shake_hand', namespace='/websocket')
    def on_shake_hand(token):
        sid = request.sid
        if sid in users.keys():
            emit('refused', '用户已存在', room=sid)
            return
        try:
            auth_check(token)
        except ValueError:
            emit('refused', 'token未加前缀Bearer', room=sid)
            return
        if g.auth_id is None:
            emit('refused', 'token错误', room=sid)
            return
        for item in users.values():
            if item['auth_id'] == g.auth_id:
                emit('refused', '用户已存在', room=sid)
                return
        users[sid] = {
            'auth_id': g.auth_id,
            'priority': g.priority
        }
        emit('accepted', '握手成功')
        print(sid, 'shake_hand', g.auth_id)
        print(users, len(users))

    @socket_io.on('message', namespace='/websocket')
    def message(json):
        sid = request.sid
        auth_id = json['auth_id']
        admin = json['admin']
        content = json['content']
        time = json['time']
        Sentence(auth_id=auth_id, admin=admin, content=content, time=time).save()
        flag = False
        if not admin:
            for key, value in users.items():
                if value['priority'] == 1:
                    emit('message', json, room=key)
                    print('发送管理员', key)
                    flag = True
            if flag:
                emit('success', '发送成功', room=sid)
            else:
                emit('failure', '没有管理员在线', room=sid)
        else:
            for key, value in users.items():
                if value['auth_id'] == auth_id:
                    emit('message', json, room=key)
                    print('发送学生', key)
                    flag = True
                    break
            if flag:
                emit('success', '发送成功', room=sid)
            else:
                emit('failure', '学生不在线', room=sid)
    return socket_io
